<template>
  <music-box title="搜索"
             theme="light">
    <!-- 搜索输入框 -->
    <view class="search-box">
      <text class="icon iconfont iconsearch"></text>
      <input type="text"
             class="input"
             v-model="searchKey"
             @confirm="search"
             @input="searchInput"
             maxlength="30"
             placeholder="请输入歌曲">
      </input>
      <view class="close iconfont iconguanbi"
            @click="searchKey = ''"
            v-show="searchKey">
      </view>
    </view>

    <view v-show="searchStatus === 0">
      <!-- 历史记录 -->
      <history :data="historyData"
               @history-item-click="toSearchClick"
               @clear-click="historyClearClick">
      </history>

      <!-- 热搜 -->
      <hot :data="hotData"
           @hot-click="toSearchClick">
      </hot>
    </view>

    <!-- 搜索提示 -->
    <search-tip v-show="searchStatus === 1"
                :title="`搜索“${searchKey.trim()}”`"
                @tip-item-click="toSearchClick"
                :data="searchTip">
    </search-tip>

    <!-- 搜索结果 -->
    <search-result v-show="searchStatus === 2"
                   :data="searchResult">
    </search-result>
  </music-box>
</template>

<script>
  import hot from './components/hot.vue'
  import history from './components/history.vue'
  import searchResult from './components/search-result.vue'
  import searchTip from './components/search-tip.vue'

  export default {
    components: { hot, history, searchResult, searchTip },
    data() {
      return {
        // 搜索关键词
        searchKey: '',
        // 搜索历史
        historyData: [],
        // 搜索热词数据
        hotData: [],
        // 搜索状态 0未搜索  1输入中，显示搜索提示  2已搜索，显示搜索结果
        searchStatus: 0,
        // 搜索结果列表
        searchResult: [],
        // 搜索提示词列表
        searchTip: [],
        // 输入定时器 用于防抖
        inputTimeout: null
      };
    },
    watch: {
      searchKey(newVal, oldVal) {
        // 当搜索值 由  有值->空值  时，searchType=false
        if (oldVal && !newVal)
          this.searchStatus = 0
      }
    },
    mounted() {
      this.getHistoryData()
      this.getHotData()
    },
    methods: {
      // 获取搜索热词数据
      async getHotData() {
        let data = await this.api.getHotList()
        if (data.code !== 200)
          return uni.$showError('获取热词失败')

        this.hotData = data.data || []
      },

      // 获取搜索历史
      getHistoryData() {
        let res = uni.getStorageSync('historyData')
        try {
          res = JSON.parse(res)
        } catch (e) {
          this.historyData = []
          return
        }
        this.historyData = res
      },

      // 获取搜索提示词
      async getSearchTip() {
        let searchKey = this.searchKey.trim()
        if (!searchKey) return this.searchTip = []

        let res = await this.api.getTipByKey(searchKey)
        if (res.code !== 200)
          return uni.$showError('获取搜索提示失败')

        this.searchStatus = 1
        this.searchTip = res.result && res.result.allMatch || []
      },

      // 关键词输入触发
      searchInput() {
        clearTimeout(this.inputTimeout)
        // 延迟300毫秒发起请求，节流
        this.inputTimeout = setTimeout(this.getSearchTip, 300)
      },

      /**
       * 搜索提示、热搜、历史记录 点击事件
       * @param {Object} key 事件回调中传回的关键词
       */
      toSearchClick(key) {
        console.log(key);
        this.searchKey = key
        // 调用搜索功能
        this.search()
      },

      // 获取搜索结果
      async getSearchResult() {
        let searchKey = this.searchKey.trim()
        let res = await this.api.getSearchByKey(searchKey)
        if (res.code !== 200)
          return uni.$showError('搜索失败')

        // 搜索结果数据处理
        this.searchResult = (res.result && res.result.songs || [])
          .map(item => {
            let singerStr = (item.artists || []).map(i => i.name).join('、')
            return {
              id: item.id || '',
              musicName: this.replaceColor(item.name || '', searchKey),
              singer: this.replaceColor(singerStr, searchKey),
              // 为9007199255011456则显示sq标志
              mark: item.mark
            }
          })

        this.searchStatus = 2
      },

      // 替换关键词颜色
      replaceColor(str, searchKey) {
        let re = new RegExp(searchKey, 'i')
        return str.replace(re, key => {
          return `<view style="color: #235790;">${key}</view>`
        })
      },

      // 搜索历史清除点击
      historyClearClick() {
        this.historyData = []
        // 异步移除搜索记录
        uni.removeStorage({
          key: 'historyData'
        })
      },

      // 搜索功能调用
      search() {
        let searchKey = this.searchKey.trim()
        if (!searchKey) return

        // 添加到历史记录
        this.addHistoryData(searchKey)

        // 获取搜索结果
        this.getSearchResult()
      },

      /**
       * 添加并保存历史记录
       * @param {string} searchKey 要添加的关键词
       */
      addHistoryData(searchKey) {
        // 如果记录已存在，则移除，然后重新添加到开头
        this.historyData.unshift(searchKey)
        this.historyData = [...new Set(this.historyData)]
        // 最多只保留10条
        this.historyData.length = Math.min(this.historyData.length, 10)

        uni.setStorageSync('historyData', JSON.stringify(this.historyData))
      }
    }
  }
</script>

<style lang="scss"
       scoped>
  .search-box {
    height: 70rpx;
    margin: 30rpx 15rpx 15rpx 15rpx;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    border-radius: 35rpx;
    background-color: #f7f7f7;

    .icon {
      font-size: 30rpx;
      padding: 4rpx 20rpx 0 28rpx;
    }

    .input {
      flex: 1;
      font-size: 26rpx;
    }

    .close {
      padding: 0 28rpx;
    }
  }
</style>
